import my from '../assets/my.png'
import styles from './index.less'
import clxs from 'classnames'
import chatgpt from '../assets/chatgpt.png'
import { PullToRefresh, } from 'antd-mobile'
import { ReactComponent as ChatGptSvg } from '../assets/chatgpt.svg'
import { ReactComponent as Copy } from '../assets/copy.svg'
import { useState, useEffect, useRef } from 'react'
import { PullStatus } from 'antd-mobile/es/components/pull-to-refresh'
import TextShow from './components/TextShow'
import { sendMessage, messageHistory } from '../services/chatgpt'
import { generateRandomString } from '../utils/utils'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { tomorrow } from 'react-syntax-highlighter/dist/esm/styles/prism'

const USER_TYPE = {
  SYSTEM: 'system',
  USER: 'user',
  ASSISTANT: 'assistant'
}
const statusRecord: Record<PullStatus, string> = {
  pulling: '下拉加载更多',
  canRelease: '松开吧',
  refreshing: '玩命加载中...',
  complete: '好啦',
}

const HomePage = () => {
  const [contentList, setContentList] = useState<Array<any>>([])
  const [inputValue, setInputValue] = useState<string>('')
  const [showGoTop, setShowGoTop] = useState<boolean>(false)
  const [showGoBottom, setShowGoBottom] = useState<boolean>(false)
  const [isLoading, setIsLoading] = useState<boolean>(false)
  const [page, setPage] = useState<number>(1)
  const [totalPage, setTotalPage] = useState<number>(0)
  const textToCopyRef = useRef(null)
  const textareaRef = useRef(null)

  useEffect(() => {
    refreshHistory(page)
    // 添加滚动事件监听器
    window.addEventListener('scroll', handleScroll)
    // 清除滚动事件监听器
    return () => {
      window.removeEventListener('scroll', handleScroll)
    }
  }, [])

  // 发送按钮
  const sendStopChange = () => {
    if (isLoading) {
      // 暂停只是暂停输出
      setIsLoading(false)
    } else if (!isLoading && inputValue?.length) {
      setIsLoading(true)
      // 添加我发送的内容
      const sendData = {
        id: generateRandomString(5),
        userType: USER_TYPE.USER,
        name: 'You',
        content: inputValue
      }
      contentList.push(sendData)
      setTimeout(scrollToBottom, 50)
      const loadingData = {
        id: 0,
        isShowText: true,
        userType: USER_TYPE.ASSISTANT,
        name: 'Deepseek',
        content: ''
      }
      contentList.push(loadingData)
      setContentList(contentList)
      setInputValue('')
      adjustTextareaHeight()
      sendMessage({ 'content': inputValue }).then(({ result }: any) => {
        const list = [...contentList]
        list.pop()
        result.isShowText = true
        if (containsCodeBlock(result.content)) {
          Reflect.set(result, 'codeStrMap', extractCode(result.content))
        }
        list.push(result)
        setContentList(list)
        setIsLoading(false)
        setTimeout(scrollToBottom, 50)
      }).catch((error: any) => {
        console.log('error:', error)
      })
    }
  }

  // 刷新列表
  const refreshHistory = (page = 1) => {
    messageHistory({ page }).then(({ result }: any) => {
      const list = [...contentList]
      const resultList = result.list.reverse()
      const newList = resultList.concat(list)
      newList.map((e: any) => {
        if (containsCodeBlock(e.content)) {
          Reflect.set(e, 'codeStrMap', extractCode(e.content))
          console.log(e)
        }
      })
      setContentList(newList)
      setTotalPage(result.totalPages)
      page === 1 && setTimeout(scrollToBottom, 50)
    })
  }

  // 添加滚动事件监听器
  const handleScroll = () => {
    // 获取滚动位置
    const scrollY = window.scrollY
    // 获取文档的总滚动高度
    const scrollHeight = Math.max(
      document.documentElement.scrollHeight,
      document.body.scrollHeight
    )
    // 根据滚动位置显示或隐藏按钮
    setShowGoBottom(scrollHeight - scrollY > 1000)
    // setShowGoTop(scrollY > 200)
  }

  const scrollToTop = () => {
    // 滚动到页面顶部
    window.scrollTo({
      top: 0,
      behavior: 'smooth',
    })
  }

  const scrollToBottom = () => {
    // 滚动到页面底部
    window.scrollTo({
      top: document.documentElement.scrollHeight,
      behavior: 'smooth',
    })
  }

  const textShowComplete = () => {
    // setIsLoading(false)
  }

  const onRefresh = async () => {
    const updatedPage = page + 1
    if (updatedPage > totalPage) {
      return
    }
    setPage(updatedPage)
    await refreshHistory(updatedPage)
  }

  // 判断字符串是否包含代码
  const containsCodeBlock = (str: string) => {
    const regex = /```[\s\S]+?```/
    return regex.test(str)
  }

  // 解析代码字符串
  const extractCode = (text: string) => {
    // 使用正则表达式匹配代码字符串
    const regex = /```(\w+)\n([^`]+)```/g
    let matches
    const codeBlocks = []
    let lastCodeEnd = 0 // 记录上一个代码块的结束位置

    while ((matches = regex.exec(text)) !== null) {
      const codeName = matches[1] // 提取代码名称
      const beforeCode = text.substring(lastCodeEnd, matches.index) // 代码前的文字
      const code = matches[2].trim() // 提取代码块
      const afterCodeIndex = matches.index + matches[0].length // 计算代码后的文字的起始索引
      const afterCode = text.substring(afterCodeIndex, regex.lastIndex) // 代码后的文字，避免包含下一个代码块之前的文字

      codeBlocks.push({ codeName, beforeCode, code, afterCode })
      lastCodeEnd = regex.lastIndex // 更新上一个代码块的结束位置
    }

    return codeBlocks
  }

  const handleTextChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    setInputValue(event.target.value)
    adjustTextareaHeight()
  }

  const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (!isLoading && event.key === 'Enter' && !event.shiftKey) {
      event.preventDefault()
      sendStopChange()
      adjustTextareaHeight()
    }
  }

  const remToPx = (remValue: number) => {
    const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize)
    const pxValue = remValue * rootFontSize
    return pxValue
  }

  const adjustTextareaHeight = () => {
    const textarea: any = textareaRef.current;
    if (textarea) {
      const lineHeight = 3 * parseFloat(getComputedStyle(textarea).fontSize);
      const rows = Math.floor(textarea.scrollHeight / lineHeight);
      if (rows === 1) {
        textarea.style.height = '3rem';
        textarea.style.lineHeight = '3rem';
        textarea.style.overflowY = 'hidden';
      } else if (rows > 1) {
        textarea.style.height = `${rows * lineHeight}px`;
        textarea.style.lineHeight = '2rem';
      }
    }
  }

  return (
    <div className={styles.box_view}>
      {!contentList.length && <div className={styles.no_data_view}>
        <div className={styles.img_view}>
          <ChatGptSvg />
        </div>
        <h2>How can I help you today?</h2>
      </div>}
      {contentList.length > 0 && <div id="list_view" className={styles.list_view}>
        <PullToRefresh
          onRefresh={onRefresh}
          renderText={status => {
            return page === totalPage ? '没有更多了' :
              <div>{statusRecord[status]}</div>
          }}
        >
          {contentList.map((e, i) => {
            return <div className={styles.msg_item} key={e.id}>
              <img className={styles.user_img} src={e.userType === USER_TYPE.USER ? my : chatgpt} alt="" />
              <div className={styles.content_view}>
                <h2 className={styles.name}>{e.name}</h2>
                {Reflect.has(e, 'codeStrMap') ? <>
                  {e.codeStrMap.map((block: any, index: any) => (
                    <div key={index}>
                      <p ref={textToCopyRef} className={styles.content} dangerouslySetInnerHTML={{ __html: block.beforeCode.replace(/\n/g, '<br>') }}></p>
                      <SyntaxHighlighter language="javascript" style={tomorrow}>
                        {block.code}
                      </SyntaxHighlighter>
                      <p ref={textToCopyRef} className={styles.content} dangerouslySetInnerHTML={{ __html: block.afterCode.replace(/\n/g, '<br>') }}></p>
                    </div>
                  ))}
                </> : e.isShowText ? <TextShow text={e.content.replace(/\n/g, '<br>')} textShowComplete={() => textShowComplete()} /> :
                  <p ref={textToCopyRef} className={styles.content} dangerouslySetInnerHTML={{ __html: e.content.replace(/\n/g, '<br>') }}></p>}
                {/* <div className={styles.actions_view}>
                    <Copy className='copy-svg'/>
                  </div> */}
              </div>
            </div>
          })}
        </PullToRefresh>

      </div>}
      <div className={styles.send_view}>
        <div className={styles.textarea_view}>
          <textarea
            ref={textareaRef}
            value={inputValue}
            placeholder='Message ChatGPT…'
            onChange={handleTextChange}
            onKeyDown={handleKeyDown}
          />
          {isLoading ?
            <span className={clxs(styles.stop_span, inputValue?.length && styles.active)} onClick={sendStopChange}>
              <svg viewBox="0 0 10 10" fill="currentColor" height="10" width="10"><path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2z" strokeWidth="0"></path>
              </svg>
            </span> :
            <span className={clxs(styles.send_span, inputValue?.length && styles.active)} onClick={sendStopChange}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <path d="M7 11L12 6L17 11M12 18V7" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path>
              </svg>
            </span>}
        </div>
      </div>

      {showGoTop && <button onClick={scrollToTop} className={styles.go_top_btn}>
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" className="m-1 text-black tomorrow:text-white"><path d="M17 13L12 18L7 13M12 6L12 17" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path></svg>
      </button>}
      {showGoBottom && <button onClick={scrollToBottom} className={styles.go_bottom_btn}>
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" className="m-1 text-black tomorrow:text-white"><path d="M17 13L12 18L7 13M12 6L12 17" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path></svg>
      </button>}

    </div>
  )
}
export default HomePage